#pragma once
#include "ace/OS_NS_unistd.h"
#include "ace\Reactor_Notification_Strategy.h"
#include "ace/Message_Queue.h"
#include "ace/Synch_Traits.h"
#include "ace/Message_Block.h"
#include "ace\condition_thread_mutex.h"
#include "ace/SOCK_Stream.h"

#include "packet_impl.h"

class tcp_syn_packet_sender
{
public:
	tcp_syn_packet_sender(void);
	virtual ~tcp_syn_packet_sender(void);
public:
	int open(ACE_Event_Handler* eh);
	int putq(aot::inet::ipacket* pkt, const aot::inet::inet_time_t* tm_out = NULL);
	int send(ACE_HANDLE h);
	ACE_Message_Queue<ACE_MT_SYNCH>* get_msg_queue();
private:
	int mb_to_iovec(iovec v[], int num, ACE_Message_Block* mb);
	size_t update_mb(size_t send_len, ACE_Message_Block* mb);
public:
	ACE_Message_Queue<ACE_MT_SYNCH>		queue_;
	ACE_Event_Handler*					eh_;
	ACE_Reactor_Notification_Strategy	notifier_;
};

/* - * - */
class tcp_syn_packet_recver
{
public:
	tcp_syn_packet_recver();
	virtual ~tcp_syn_packet_recver(void);
public:
	int open();
	int getq(aot::inet::ipacket** pkt, const aot::inet::inet_time_t* tm_out);
	int recv(ACE_HANDLE h, tcp_syn_packet_sender* pkt_sender);
private:
	int recv_i(ACE_HANDLE h);
	bool process_packet(tcp_syn_packet_sender* pkt_sender);
public:
	packet_impl*		pkt_;
	ACE_Message_Queue<ACE_MT_SYNCH>		queue_;
};